﻿
Imports std

Public Class machine_selector
    Inherits vector(Of String)

    Public Const separator As Char = character.sheffer

    Private Shared Function isseparator(ByVal c As Char) As Boolean
        Return c = separator
    End Function

    Private Shared Function isnotseparator(ByVal c As Char) As Boolean
        Return Not isseparator(c)
    End Function

    Private Shared Function valid_first(ByVal c As Char) As Boolean
        Return isnotspace(c) AndAlso isnotseparator(c) AndAlso _
               Not [step].isseparator(c) AndAlso Not distrrule.isseparator(c)
    End Function

    Private Shared Function valid_other(ByVal c As Char) As Boolean
        Return valid_first(c)
    End Function

    Public Shared Function parse(ByVal rule As String, ByRef index As Int64, _
                                 ByRef output As machine_selector) As Boolean
        output = New machine_selector()
        Dim s As String = Nothing
        While token(rule, index, s, AddressOf valid_first, AddressOf valid_other)
            output.push_back(s)
            If Not token(rule, index, Nothing, AddressOf isseparator, AddressOf [false]) Then
                Exit While
            End If
        End While

        Return output.size() > 0
    End Function

    Public Overrides Function ToString() As String
        Return MyBase.ToString(separator)
    End Function
End Class

Public Class [step]
    Inherits vector(Of machine_selector)

    Public Const separator As Char = character.andMark

    Friend Shared Function isseparator(ByVal c As Char) As Boolean
        Return c = separator
    End Function

    Public Shared Function parse(ByVal rule As String, ByRef index As Int64, _
                                 ByRef output As [step]) As Boolean
        output = New [step]()
        Dim s As machine_selector = Nothing
        While machine_selector.parse(rule, index, s)
            output.push_back(s)
            If Not token(rule, index, Nothing, AddressOf isseparator, AddressOf [false]) Then
                Exit While
            End If
        End While

        Return output.size() > 0
    End Function

    Public Overrides Function ToString() As String
        Return MyBase.ToString(separator)
    End Function
End Class

Public Class distrrule
    Inherits vector(Of [step])

    Public Const separator As Char = character.semicolon

    Friend Shared Function isseparator(ByVal c As Char) As Boolean
        Return c = separator
    End Function

    Private raw As String = Nothing

    Public Function rule() As String
        Return raw
    End Function

    Public Shared Function parse(ByVal rule As String, ByRef output As distrrule) As Boolean
        output = New distrrule()
        Dim s As [step] = Nothing
        Dim index As Int64 = 0
        While [step].parse(rule, index, s)
            output.push_back(s)
            If Not token(rule, index, Nothing, AddressOf isseparator, AddressOf [false]) Then
                Exit While
            End If
        End While

        If index = strlen(rule) AndAlso output.size() > 0 Then
            copy(output.raw, rule)
            Return True
        Else
            Return False
        End If
    End Function

    Public Overrides Function ToString() As String
        Return MyBase.ToString(separator)
    End Function
End Class

Public Class distrrule_map
    Inherits map(Of String, distrrule)

    Public Overloads Function insert(ByVal n As String, ByVal r As String) As iterator
        Dim rule As distrrule = Nothing
        If distrrule.parse(r, rule) Then
            Return insert(n, rule)
        Else
            Return [end]()
        End If
    End Function

    Public Overloads Function find(ByVal n As String, ByRef r As distrrule) As Boolean
        Dim it As distrrule_map.iterator = Nothing
        it = find(n)
        If it = [end]() Then
            Return False
        Else
            r = (+it).second
            Return True
        End If
    End Function
End Class
